
package com.jf.cloud.user.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.PhoneUtil;
import cn.hutool.core.util.StrUtil;
import com.jf.cloud.api.auth.constant.SysTypeEnum;
import com.jf.cloud.api.auth.dto.AuthAccountDTO;
import com.jf.cloud.api.auth.dto.AuthAccountWithSocialDTO;
import com.jf.cloud.api.auth.feign.AccountFeignClient;
import com.jf.cloud.api.auth.feign.TokenFeignClient;
import com.jf.cloud.api.auth.vo.AuthAccountVO;
import com.jf.cloud.api.coupon.feign.CouponFeignClient;
import com.jf.cloud.api.coupon.vo.CouponUserCountDataVO;
import com.jf.cloud.api.distribution.bo.DistributionUserUpdateBO;
import com.jf.cloud.api.leaf.feign.SegmentFeignClient;
import com.jf.cloud.api.order.dto.QueryOrderDTO;
import com.jf.cloud.api.order.feign.OrderFeignClient;
import com.jf.cloud.api.user.bo.UidAndUserIdBO;
import com.jf.cloud.api.user.vo.MemberOverviewVO;
import com.jf.cloud.api.user.vo.UserApiVO;
import com.jf.cloud.api.user.vo.UserManagerVO;
import com.jf.cloud.common.cache.constant.UserCacheNames;
import com.jf.cloud.common.cache.util.RedisUtil;
import com.jf.cloud.common.constant.Constant;
import com.jf.cloud.common.constant.DistributedIdKey;
import com.jf.cloud.common.database.dto.PageDTO;
import com.jf.cloud.common.database.util.PageAdapter;
import com.jf.cloud.common.database.util.PageUtil;
import com.jf.cloud.common.database.vo.PageVO;
import com.jf.cloud.common.exception.LuckException;
import com.jf.cloud.common.order.vo.UserOrderStatisticVO;
import com.jf.cloud.common.response.ResponseEnum;
import com.jf.cloud.common.response.ServerResponseEntity;
import com.jf.cloud.common.rocketmq.config.RocketMqConstant;
import com.jf.cloud.common.security.AuthUserContext;
import com.jf.cloud.common.util.IpHelper;
import com.jf.cloud.common.util.PriceUtil;
import com.jf.cloud.user.constant.LevelTypeEnum;
import com.jf.cloud.user.constant.OrderSortEnum;
import com.jf.cloud.user.dto.ShopCustomerDTO;
import com.jf.cloud.user.dto.UserDTO;
import com.jf.cloud.user.dto.UserManagerDTO;
import com.jf.cloud.user.mapper.UserMapper;
import com.jf.cloud.user.model.User;
import com.jf.cloud.user.model.UserExtension;
import com.jf.cloud.user.service.*;
import com.jf.cloud.user.vo.ShopCustomerVO;
import com.jf.cloud.user.vo.UserVO;
import io.seata.common.util.CollectionUtils;
import io.seata.spring.annotation.GlobalTransactional;
import ma.glasnost.orika.MapperFacade;
import org.apache.rocketmq.client.producer.SendStatus;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.messaging.support.GenericMessage;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 用户表
 *
 * @author zz
 * @date 2020-12-08 11:18:04
 */
@Service
public class UserServiceImpl implements UserService {

    @Value("${jfcloud.expose.operation.auth:}")
    private Boolean permission;

    @Autowired
    private UserMapper userMapper;
    @Autowired
    private UserExtensionService userExtensionService;
    @Autowired
    private UserLevelService userLevelService;
    @Autowired
    private UserAddrService userAddrService;

    @Autowired
    private UserConsigneeService userConsigneeService;
    @Autowired
    private UserGrowthLogService userGrowthLogService;
    @Autowired
    private UserLevelLogService userLevelLogService;
    @Autowired
    private UserScoreGetLogService userScoreGetLogService;
    @Autowired
    private UserScoreLockService userScoreLockService;
    @Autowired
    private UserScoreLogService userScoreLogService;
    @Autowired
    private UserTagUserService userTagUserService;
    @Autowired
    private AccountFeignClient accountFeignClient;
    @Autowired
    private TokenFeignClient tokenFeignClient;
    @Autowired
    private MapperFacade mapperFacade;
    @Autowired
    private SegmentFeignClient segmentFeignClient;
    @Autowired
    private OrderFeignClient orderFeignClient;
    @Autowired
    private CouponFeignClient couponFeignClient;
    @Autowired
    private RocketMQTemplate userNotifyDistributionUserTemplate;

    @Autowired
    private ShopCustomerService shopCustomerService;

    @Override
    public PageVO<UserApiVO> page(PageDTO pageDTO, UserManagerDTO userManagerDTO) {
        return PageUtil.doPage(pageDTO, () -> userMapper.list(userManagerDTO));
    }

    @Override
    @Cacheable(cacheNames = UserCacheNames.USER_INFO, key = "#userId")
    public UserApiVO getByUserId(Long userId) {
        UserApiVO userApiVO = userMapper.getByUserId(userId);
        if (Objects.isNull(userApiVO)) {
            return userApiVO;
        }
        ServerResponseEntity<AuthAccountVO> accountResponse = accountFeignClient.getInsiderDataByUserIdAndSysType(userId, SysTypeEnum.ORDINARY.value());        if (accountResponse.isFail()) {
            throw new LuckException(accountResponse.getMsg());
        }
        if (Objects.nonNull(accountResponse.getData())) {
            userApiVO.setUserName(accountResponse.getData().getUsername());
        }

        return userApiVO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(cacheNames = UserCacheNames.USER_INFO, key = "#user.userId")
    public void update(User user) {
        userMapper.update(user);
        // USER_NOTIFY_DISTRIBUTION_USER_TOPIC
        // 如果有一项不为空，修改分销员信息（如果是分销员）
        if (StrUtil.isNotBlank(user.getPic()) || StrUtil.isNotBlank(user.getNickName())) {
            DistributionUserUpdateBO distributionUserUpdateBO = new DistributionUserUpdateBO();
            distributionUserUpdateBO.setUserId(user.getUserId());
            distributionUserUpdateBO.setNickName(user.getNickName());
            distributionUserUpdateBO.setPic(user.getPic());
            //通知分销服务， 修改分销员的昵称和分销员的头像
            SendStatus sendStockStatus = userNotifyDistributionUserTemplate.syncSend(RocketMqConstant.USER_NOTIFY_DISTRIBUTION_USER_TOPIC, new GenericMessage<>(distributionUserUpdateBO)).getSendStatus();
            if (!Objects.equals(sendStockStatus, SendStatus.SEND_OK)) {
                throw new LuckException(ResponseEnum.EXCEPTION);
            }
        }
    }

    @Override
    public User getById(Long userId) {
        return userMapper.getById(userId);
    }

    @Override
    @CacheEvict(cacheNames = UserCacheNames.USER_INFO, key = "#userId")
    public void removeUserCacheByUserId(Long userId) {
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateUserLevel(Integer level, int minGrowth, Integer maxGrowth) {
        userMapper.updateUserLevel(level, minGrowth, maxGrowth);
        userExtensionService.updateUserLevel(level, minGrowth, maxGrowth);
    }

    @Override
    public List<UserApiVO> getUserByUserIds(List<Long> userIds) {
        if (CollUtil.isEmpty(userIds)) {
            return new ArrayList<>();
        }
        return userMapper.getUserByUserIds(userIds);
    }

    @Override
    public UserApiVO getUserAndOpenIdsByUserId(Long userId) {
        UserApiVO userApiVO = userMapper.getByUserId(userId);
        List<String> ids =  accountFeignClient.getBizUserIdListByUserId(userId).getData();
        userApiVO.setBizUserIdList(ids);
        return userApiVO;
    }

    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    @Transactional(rollbackFor = Exception.class)
    public UidAndUserIdBO save(String mobile, String password, String tempUid){
        ServerResponseEntity<Long> segmentIdResponse = segmentFeignClient.getSegmentId(DistributedIdKey.MALL4CLOUD_USER);
        if (!segmentIdResponse.isSuccess()) {
            throw new LuckException(ResponseEnum.EXCEPTION);
        }
        Long userId = segmentIdResponse.getData();

        AuthAccountDTO authAccountDTO = new AuthAccountDTO();
        authAccountDTO.setCreateIp(IpHelper.getIpAddr());
        authAccountDTO.setPassword(password);
        authAccountDTO.setPhone(mobile);
        authAccountDTO.setIsAdmin(0);
        authAccountDTO.setSysType(SysTypeEnum.ORDINARY.value());
        authAccountDTO.setStatus(1);
        authAccountDTO.setUserId(userId);

        AuthAccountWithSocialDTO authAccountWithSocialDTO = new AuthAccountWithSocialDTO();
        authAccountWithSocialDTO.setAuthAccount(authAccountDTO);
        authAccountWithSocialDTO.setTempUid(tempUid);

        // 保存统一账户信息
        ServerResponseEntity<Long> serverResponse = accountFeignClient.saveAccountWithSocial(authAccountWithSocialDTO);
        // 抛异常回滚
        if (!serverResponse.isSuccess()) {
            throw new LuckException(serverResponse.getMsg());
        }

        User user = new User();
        user.setUserId(userId);
        user.setLevel(Constant.USER_LEVEL_INIT);
        user.setLevelType(LevelTypeEnum.ORDINARY_USER.value());
        user.setStatus(1);
        user.setPhone(authAccountDTO.getPhone());
        // 昵称默认位u + 手机尾号后4位
        user.setNickName("u" + mobile.substring(7));
        // 默认开启商品个性化推荐
        user.setProdRecommendation(1);
        user.setOrgId(null);
        // 这里保存之后才有用户id
        userMapper.save(user);

        UserExtension userExtension = new UserExtension();
        userExtension.setBalance(0L);
        userExtension.setActualBalance(0L);
        userExtension.setGrowth(0);
        userExtension.setLevel(1);
        userExtension.setLevelType(0);
        userExtension.setScore(0L);
        userExtension.setVersion(0);
        userExtension.setSignDay(0);
        // 上面保存这边才能拿到userId
        userExtension.setUserId(user.getUserId());

        userExtensionService.save(userExtension);
        //用户注册成功后初始化用户数据
        userLevelService.initUserInfoAndLevelInfo(userExtension,Constant.USER_LEVEL_INIT, LevelTypeEnum.ORDINARY_USER.value(),authAccountDTO.getPhone());

        return new UidAndUserIdBO(serverResponse.getData(), userId);
    }

    @Override
    @CacheEvict(cacheNames = UserCacheNames.USER_INFO, key = "#userId")
    @GlobalTransactional(rollbackFor = Exception.class)
    @Transactional(rollbackFor = Exception.class)
    public void updateUserMobile(Long userId, String mobile) {
        AuthAccountDTO authAccountDTO = new AuthAccountDTO();
        authAccountDTO.setUserId(userId);
        authAccountDTO.setPhone(mobile);
        authAccountDTO.setSysType(SysTypeEnum.ORDINARY.value());
        ServerResponseEntity<Void> voidServerResponseEntity = accountFeignClient.updateUserMobile(authAccountDTO);
        if (!voidServerResponseEntity.isSuccess()){
            throw new LuckException(voidServerResponseEntity.getMsg());
        }
        // 更新user表手机号
        User user = new User();
        user.setUserId(userId);
        user.setPhone(mobile);
        userMapper.update(user);
    }

    @Override
    public PageVO<UserManagerVO> getUserInfoPage(PageDTO pageDTO, UserManagerDTO userManagerDTO) {
        PageVO<UserManagerVO> pageVO = new PageVO<>();
        // 用户信息
        Long userTotal = userMapper.countUserPageByParam(userManagerDTO);
        pageVO.setTotal(userTotal);
        pageVO.setPages(PageUtil.getPages(pageVO.getTotal(), pageDTO.getPageSize()));
        if (Objects.equals(0L, userTotal)) {
            pageVO.setList(Collections.emptyList());
            return pageVO;
        }
        List<UserManagerVO> userList = getUserInfoList(pageDTO, userManagerDTO);
        pageVO.setList(userList);
        return pageVO;
    }

    @Override
    public List<UserManagerVO> getUserInfoList(PageDTO pageDTO, UserManagerDTO userManagerDTO) {
        // 从用户表中查询数据，并且初始化一些相关订单变量的数据，就不用在后面再次设置相关相关初始值了
        List<UserManagerVO> userList = userMapper.listUserByParam(userManagerDTO, new PageAdapter(pageDTO));
        for (UserManagerVO userManagerVO : userList) {
            // 将余额由分转为元
            BigDecimal currentBalance = userManagerVO.getCurrentBalance();
            BigDecimal sumBalance = userManagerVO.getSumBalance();
            userManagerVO.setCurrentBalance(PriceUtil.toDecimalPrice(currentBalance.longValue()));
            userManagerVO.setSumBalance(PriceUtil.toDecimalPrice(sumBalance.longValue()));
            userManagerVO.setRechargeAmount(PriceUtil.toDecimalPrice(userManagerVO.getRechargeAmount().longValue()));
            //读取到环境变量后隐藏手机号码
            if (BooleanUtil.isFalse(permission)){
                userManagerVO.setPhone(PhoneUtil.hideBetween(userManagerVO.getPhone()).toString());
            }
        }
        List<Long> userIds = userList.stream().map(UserManagerVO::getUserId).collect(Collectors.toList());

        // 统计用户的订单相关信息
        // eg说明：查询10个用户的订单，但是只有3个用户有下单记录，所以这里只会返回3条数据，
        // 另外的7条记录保持默认值即可，应该在查询用户的时候已经设置了默认值了，所以不需要设置默认值
        QueryOrderDTO queryOrderDTO = new QueryOrderDTO();
        queryOrderDTO.setUserIds(new ArrayList<>(userIds));
        queryOrderDTO.setShopId(AuthUserContext.get().getTenantId());
        ServerResponseEntity<List<UserOrderStatisticVO>> orderResponse = orderFeignClient.countOrderByUserIds(queryOrderDTO);
        if (!Objects.equals(orderResponse.getCode(), ResponseEnum.OK.value())) {
            throw new LuckException(orderResponse.getMsg());
        }
        List<UserOrderStatisticVO> data = orderResponse.getData();
        // 组装订单统计数据
        if (CollectionUtils.isNotEmpty(data)) {
            Map<Long, UserOrderStatisticVO> userOrderMap = data.stream().collect(Collectors.toMap(UserOrderStatisticVO::getUserId, (k) -> k));
            assemblyUserData(userList, userOrderMap);
        }
        return userList;
    }

    @Override
    public UserManagerVO getUserInfo(Long userId) {
        PageDTO pageDTO = new PageDTO();
        pageDTO.setPageNum(0);
        pageDTO.setPageSize(1);
        UserManagerDTO userManagerDTO = new UserManagerDTO();
        userManagerDTO.setUserIds(Collections.singletonList(userId));
        PageVO<UserManagerVO> infoPage = getUserInfoPage(pageDTO, userManagerDTO);
        if (infoPage.getTotal() < 1) {
            throw new LuckException("该用户不存在");
        }
        UserManagerVO userManagerVO = infoPage.getList().get(0);
        // 统计用户优惠券相关信息
        ServerResponseEntity<CouponUserCountDataVO> couponUserResponse = couponFeignClient.countCouponUserByUserId(userId);
        if (!Objects.equals(couponUserResponse.getCode(), ResponseEnum.OK.value())) {
            throw new LuckException(couponUserResponse.getMsg());
        }
        userManagerVO.setCouponUserCountDataVO(couponUserResponse.getData());
        return userManagerVO;
    }

    @Override
    public void updateUserLevelByUserExtensionAndUserIds(List<Long> userIds) {
        userMapper.updateUserLevelByUserExtensionAndUserIds(userIds);
    }


    @Override
    @CacheEvict(cacheNames = UserCacheNames.USER_INFO, key = "#userDTO.userId")
    @GlobalTransactional(rollbackFor = Exception.class)
    @Transactional(rollbackFor = Exception.class)
    public void updateUserInfo(UserDTO userDTO) {
        Long userId = userDTO.getUserId();
        Integer status = userDTO.getStatus();
        UserApiVO userApiVO = userMapper.getByUserId(userId);
        boolean isUpdateStatus = Objects.equals(userApiVO.getStatus(), status);
        User user = new User();
        user.setUserId(userDTO.getUserId());
        user.setNickName(userDTO.getNickName());
        if (!isUpdateStatus) {
            user.setStatus(status);
        }
        user.setUpdateTime(DateUtil.date());
        // 更新用户表信息
        this.update(user);
        // 如果用户状态未发生改变，就不需要修改账户表中用户的状态
        if (isUpdateStatus) {
            return;
        }
        // 修改用户状态时需要修改auth_account表的状态,同时需要将用户下线
        AuthAccountDTO authAccountDTO = new AuthAccountDTO();
        authAccountDTO.setUserId(user.getUserId());
        authAccountDTO.setSysType(SysTypeEnum.ORDINARY.value());
        authAccountDTO.setStatus(user.getStatus());
        ServerResponseEntity<Void> updateResponse = accountFeignClient.updateAuthAccountStatusAndDeleteUserToken(authAccountDTO);
        if (!Objects.equals(updateResponse.getCode(), ResponseEnum.OK.value())) {
            throw new LuckException(updateResponse.getMsg());
        }

    }

    @Override
    public List<UserVO> getUserListByPhones(List<String> phones) {
        if (CollUtil.isEmpty(phones)) {
            return Collections.emptyList();
        }
        return userMapper.getUserListByPhones(phones);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void batchUser(List<User> userList, List<UserExtension> userExtensionList) {
        if (CollUtil.isEmpty(userList)) {
            return;
        }
        // 新增用户
        int row = userMapper.saveBatch(userList);
        if (row == 0) {
            return;
        }
        // userList 的大小 不等于 插入row的行数，所以我们要查询插入的用户是那些
        // 如果是已经存在的userId在 userExtensionList中也不要紧，在保存sql的时候会排除掉数据库中已经存在的userId
        List<Long> userIds = userList.stream().map(User::getUserId).collect(Collectors.toList());
        List<UserApiVO> userApiVOList = userMapper.getUserByUserIds(userIds);
        List<Long> dbUserIds = userApiVOList.stream().map(UserApiVO::getUserId).collect(Collectors.toList());
        userExtensionList = userExtensionList.stream().filter(item -> dbUserIds.contains(item.getUserId())).collect(Collectors.toList());
        userExtensionService.saveBatch(userExtensionList);
        // 积分、成长值、余额日志
        userExtensionService.registerUserScoreGrowthBalanceLog(userExtensionList);
        // 赠送注册积分
        userLevelService.registerUserScore(userExtensionList);
        // 导入后赠送等级相关的积分和权益
        userLevelService.registerUserSendRights(userExtensionList);
    }

    @Override
    public List<UserVO> getUserByCreateTimeRange(Integer status, Date startDate, Date endDate) {
        return userMapper.getUserByCreateTimeRange(status, startDate, endDate);
    }

    @Override
    public MemberOverviewVO getUserCountInfo(Date endTime) {
        Date startTime = DateUtil.beginOfDay(endTime);
        MemberOverviewVO memberOverviewListVO = userMapper.getUserCountInfo(startTime, endTime);
        return memberOverviewListVO;
    }

    @Override
    public Integer countUserByMobile(String mobile) {
        return userMapper.countUserByMobile(mobile);
    }

    @Override
    public Integer countUserByLevel(Integer level, Integer levelType) {
        return userMapper.countUserByLevel(level,levelType);
    }

    @Override
    public List<UserVO> selectMemberByEndTime(DateTime endOfDay) {
        return userMapper.selectMemberByEndTime(endOfDay);
    }

    @Override
    public void updateUserTypeLevelByUserExtensionAndUserIds(List<Long> userIds) {
        userMapper.updateUserTypeLevelByUserExtensionAndUserIds(userIds);
    }

    @Override
    public List<Long> getUserIdListByLevel(Integer levelType) {
        return userMapper.getUserIdListByLevel(levelType);
    }


    private List<UserManagerVO> assemblyUserData(List<UserManagerVO> userList, Map<Long, UserOrderStatisticVO> userOrderMap) {
        for (UserManagerVO userManagerVO : userList) {
            UserOrderStatisticVO orderStatisticVO = userOrderMap.get(userManagerVO.getUserId());
            if (Objects.isNull(orderStatisticVO)) {
                userManagerVO.setActualAmount(new BigDecimal(0));
                userManagerVO.setConsAmount(new BigDecimal(0));
                userManagerVO.setConsTimes(0);
                userManagerVO.setAfterSaleAmount(new BigDecimal(0));
                userManagerVO.setAfterSaleTimes(0);
                userManagerVO.setAllCount(0);
                continue;
            }
            BigDecimal rechargeAmount = Objects.nonNull(userManagerVO.getRechargeAmount()) ? userManagerVO.getRechargeAmount() : new BigDecimal(0) ;
            // 实付金额 累计支付的金额: 除了余额支付/积分支付的订单累计金额 + 余额充值金额
            userManagerVO.setActualAmount(PriceUtil.toDecimalPrice(orderStatisticVO.getActualAmount().longValue()).add(rechargeAmount));
            // 最近支付下单时间
            Date reConsTime1 = orderStatisticVO.getReConsTime();
            // 最近余额充值时间
            Date reConsTime2 = userManagerVO.getReConsTime();
            // 最近消费时间 reConsTime1 reConsTime2 比较
            if (Objects.isNull(reConsTime2)) {
                userManagerVO.setReConsTime(reConsTime1);
            } else if (Objects.nonNull(reConsTime1)) {
                userManagerVO.setReConsTime(DateUtil.compare(reConsTime1,reConsTime2) >= 0?reConsTime1:reConsTime2);
            }
            userManagerVO.setConsAmount(PriceUtil.toDecimalPrice(orderStatisticVO.getConsAmount().longValue()));
            userManagerVO.setConsTimes(orderStatisticVO.getConsTimes());
            userManagerVO.setAverDiscount(orderStatisticVO.getAverDiscount());
            userManagerVO.setAfterSaleAmount(PriceUtil.toDecimalPrice(orderStatisticVO.getAfterSaleAmount().longValue()));
            userManagerVO.setAfterSaleTimes(orderStatisticVO.getAfterSaleTimes());
            userManagerVO.setAllCount(orderStatisticVO.getAllCount());
        }
        return userList;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @GlobalTransactional(rollbackFor = Exception.class)
    public void destroyUser(Long userId) {

        userMapper.deleteById(userId);
        userAddrService.deleteUserAddrByUserId(null, userId);
        UserExtension userExtension = userExtensionService.getByUserId(userId);
        userExtensionService.deleteById(userExtension.getUserExtensionId());
        userConsigneeService.deleteByUserId(userId);
        userGrowthLogService.deleteByUserId(userId);
        userScoreGetLogService.deleteByUserId(userId);
        userScoreLockService.deleteByUserId(userId);
        userScoreLogService.deleteByUserId(userId);
        userTagUserService.deleteByUserId(userId);
        accountFeignClient.deleteByUserIdAndSysType(userId);
        tokenFeignClient.clearToken();
        RedisUtil.del(UserCacheNames.USER_INFO + UserCacheNames.UNION + userId);
    }

    @Override
    public PageVO<UserManagerVO> list(PageDTO pageDTO, UserManagerDTO userManagerDTO) {

        return null;
    }

    @Override
    public List<UserApiVO> getUserByParam(UserApiVO userApiVO) {
        return userMapper.getUserByParam(userApiVO);
    }

    @Override
    public PageVO<UserManagerVO> pageShopCustomerByParam(PageDTO pageDTO, ShopCustomerDTO shopCustomerDTO) {
        List<UserManagerVO> users = shopCustomerService.listByParam(shopCustomerDTO);
        if(CollUtil.isEmpty(users)){
            return new PageVO<>();
        }
        List<Long> userIdList = users.stream().map(UserManagerVO::getUserId).collect(Collectors.toList());
        ServerResponseEntity<List<UserManagerVO>> pageVOServerResponseEntity = orderFeignClient.listOrderByUserIdsAndShopId(pageDTO, userIdList, shopCustomerDTO.getShopId(), shopCustomerDTO.getSort());
        List<UserManagerVO> orderData = pageVOServerResponseEntity.getData();

        Map<Long, UserManagerVO> orderDataMap = orderData.stream().collect(Collectors.toMap(UserManagerVO::getUserId, (u) -> u));
        for(UserManagerVO userManagerVO : users){
            UserManagerVO userOrderData = orderDataMap.get(userManagerVO.getUserId());
            userManagerVO.setReConsTime(Objects.nonNull(userOrderData) ? userOrderData.getReConsTime() : null);
            userManagerVO.setConsTimes(Objects.nonNull(userOrderData) ? userOrderData.getConsTimes() : 0);
            userManagerVO.setAllCount(Objects.nonNull(userOrderData) ? userOrderData.getAllCount() : 0);
            userManagerVO.setAverDiscount(Objects.nonNull(userOrderData) ? userOrderData.getAverDiscount() : new BigDecimal(0));
            userManagerVO.setConsAmount(Objects.nonNull(userOrderData) ? PriceUtil.toDecimalPrice(userOrderData.getConsAmount().longValue()) : new BigDecimal(0));
            userManagerVO.setAfterSaleAmount(Objects.nonNull(userOrderData) ? PriceUtil.toDecimalPrice(userOrderData.getAfterSaleAmount().longValue()) : new BigDecimal(0));
            userManagerVO.setActualAmount(Objects.nonNull(userOrderData) ? PriceUtil.toDecimalPrice(userOrderData.getActualAmount().longValue()) : new BigDecimal(0));
            userManagerVO.setAfterSaleTimes(Objects.nonNull(userOrderData) ? userOrderData.getAfterSaleTimes() : 0);

            if(BooleanUtil.isFalse(permission)){
                userManagerVO.setPhone(PhoneUtil.hideBetween(userManagerVO.getPhone()).toString());
            }
        }
        Integer sort = shopCustomerDTO.getSort();
        if(Objects.equals(shopCustomerDTO.getSort(), OrderSortEnum.ALL_COUNT_ASC.value())){
            users.sort(Comparator.comparing(UserManagerVO::getAllCount));
        }else if(Objects.equals(sort, OrderSortEnum.ALL_COUNTC_DESC.value())){
            users.sort(Comparator.comparing(UserManagerVO::getAllCount).reversed());
        }else if(Objects.equals(sort, OrderSortEnum.AVER_DISCOUNT_ASC.value())){
            users.sort(Comparator.comparing(UserManagerVO::getAverDiscount));
        }else if(Objects.equals(sort, OrderSortEnum.AVER_DISCOUNT_DESC.value())){
            users.sort(Comparator.comparing(UserManagerVO::getAverDiscount).reversed());
        }else if(Objects.equals(sort, OrderSortEnum.AFTER_SALE_TIMES_ASC.value())){
            users.sort(Comparator.comparing(UserManagerVO::getAfterSaleTimes));
        }else if(Objects.equals(sort, OrderSortEnum.AFTER_SALE_TIMES_DESC.value())){
            users.sort(Comparator.comparing(UserManagerVO::getAfterSaleTimes).reversed());
        }else if(Objects.equals(sort, OrderSortEnum.AFTER_SALE_AMOUNT_ASC.value())){
            users.sort(Comparator.comparing(UserManagerVO::getAfterSaleAmount));
        }else if(Objects.equals(sort, OrderSortEnum.AFTER_SALE_AMOUNT_DESC.value())){
            users.sort(Comparator.comparing(UserManagerVO::getAfterSaleAmount).reversed());
        } else if (Objects.equals(sort, OrderSortEnum.CONS_AMOUNT_ASC.value())) {
            users.sort(Comparator.comparing(UserManagerVO::getConsAmount));
        }else if (Objects.equals(sort, OrderSortEnum.CONS_AMOUNT_DESC.value())) {
            users.sort(Comparator.comparing(UserManagerVO::getConsAmount).reversed());
        } else if (Objects.equals(sort, OrderSortEnum.ACTUAL_AMOUNT_ASC.value())) {
            users.sort(Comparator.comparing(UserManagerVO::getActualAmount));
        }else if(Objects.equals(sort, OrderSortEnum.ACTUAL_AMOUNT_DESC.value())) {
            users.sort(Comparator.comparing(UserManagerVO::getActualAmount).reversed());
        }else if(Objects.equals(sort, OrderSortEnum.CONS_TIMES_ASC.value())) {
            users.sort(Comparator.comparing(UserManagerVO::getConsTimes));
        } else if (Objects.equals(sort, OrderSortEnum.CONS_TIMES_DESC.value())) {
            users.sort(Comparator.comparing(UserManagerVO::getConsTimes).reversed());
        }
        PageVO<UserManagerVO> pageVO = new PageVO<>();
        List<UserManagerVO> result = users.stream().skip((pageDTO.getPageNum() - 1) * pageDTO.getPageSize()).limit(pageDTO.getPageSize()).collect(Collectors.toList());
        pageVO.setTotal((long) users.size());
        pageVO.setPages((users.size() - 1) / pageDTO.getPageSize() + 1);
        pageVO.setList(result);
        return pageVO;
    }

    @Override
    public Long countOrgUser() {
        return userMapper.countOrgUser();
    }
}
